// 文件路径: src/main/java/com/chixing/controller/TransactionController.java

package com.chixing.controller;

import com.alipay.api.request.AlipayTradeRefundRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chixing.config.AlipayConfig;
import com.chixing.entity.OrderBase;
import com.chixing.entity.OrderDetail;
import com.chixing.entity.Transaction;
import com.chixing.service.IOrderBaseService;
import com.chixing.service.IOrderDetailService;
import com.chixing.service.ITransactionService;
import com.chixing.service.IUserCouponService;
import com.chixing.service.impl.OrderBaseServiceImpl;
import com.chixing.service.impl.SeatStatusService;
import com.chixing.util.Result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Flow;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author liwenjing
 * @since 2025-10-07
 */
@CrossOrigin
@RestController
@RequestMapping("/transaction")
public class TransactionController {

    @Autowired
    private ITransactionService transactionService;
    @Autowired
    private IOrderBaseService orderBaseService;
    @Autowired
    private IUserCouponService userCouponService;
    @Autowired
    private SeatStatusService seatStatusService;
    @Autowired
    private IOrderDetailService orderDetailService;
    @PostMapping("/pay")
    public String alipay(@RequestBody OrderBase orderBase, HttpServletResponse response) throws AlipayApiException {
        System.out.println("支付请求，订单ID = " + orderBase.getOrderId());

        // 1. 初始化支付宝客户端
        DefaultAlipayClient alipayClient = new DefaultAlipayClient(
                AlipayConfig.gatewayUrl,
                AlipayConfig.app_id,
                AlipayConfig.merchant_private_key,
                "json",
                AlipayConfig.charset,
                AlipayConfig.alipay_public_key,
                AlipayConfig.sign_type
        );

        // 2. 创建支付请求
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url); // 同步回调地址
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);  // 异步回调地址

        // 3. 组装支付参数（使用订单编号、最终价格、订单id）
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + orderBase.getOrderNumber() + "\","
                + "\"total_amount\":\"" + orderBase.getFinalPrice() + "\","
                + "\"subject\":\"电影票订单-" + orderBase.getOrderId() + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        // 4. 调用支付宝接口，返回支付表单
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        System.out.println("支付请求响应：" + result);
        return result;
    }

    /**
     * 支付宝同步回调（支付成功后跳转）
     */
    @GetMapping("/returnNotice")
    public void alipayReturnNotice(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("同步回调：支付成功");

        try {
            // 1. 解析回调参数（需转码处理）
            String orderNumber = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            String payAmount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println("订单编号：" + orderNumber);
            System.out.println("支付宝交易号：" + tradeNo);
            System.out.println("支付金额：" + payAmount);

            // 2. 查询订单信息
            OrderBase orderBase = orderBaseService.getAllOrders().stream()
                    .filter(order -> orderNumber.equals(order.getOrderNumber()))
                    .findFirst()
                    .orElseThrow(() -> new RuntimeException("订单不存在"));

            // 3. 创建交易流水并更新状态
            Result result = transactionService.handlePaymentSuccess(
                    orderBase.getOrderId(),
                    orderBase.getUserId(),
                    new BigDecimal(payAmount),
                    tradeNo
            );

            // 4. 跳转至流水详情页
            Transaction transaction = (Transaction) result.getData();
            String vueUrl = "http://localhost:5173/PaymentFlow/" + transaction.getTransactionId();
            response.sendRedirect(vueUrl);

        } catch (Exception e) {
            e.printStackTrace();
            response.sendRedirect("http://localhost:5173/payFail"); // 支付失败页面
        }
    }

    /**
     * 支付宝异步回调（后台处理）
     */
    @PostMapping("/notifyNotice")
    @ResponseBody
    public String alipayNotifyNotice(HttpServletRequest request) throws UnsupportedEncodingException {
        System.out.println("异步回调：支付成功");

        // 1. 解析回调参数
        String orderNumber = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String tradeNo = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        String payAmount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

        // 2. 处理支付结果（重复处理幂等性保证）
        try {
            OrderBase orderBase = orderBaseService.getAllOrders().stream()
                    .filter(order -> orderNumber.equals(order.getOrderNumber()))
                    .findFirst()
                    .orElseThrow(() -> new RuntimeException("订单不存在"));

            // 3. 幂等性判断：如果订单已支付则直接返回成功
            if (orderBase.getStatues() == 1) { // 假设1为"已支付"状态
                return "success";
            }

            // 4. 处理支付成功逻辑
            transactionService.handlePaymentSuccess(
                    orderBase.getOrderId(),
                    orderBase.getUserId(),
                    new BigDecimal(payAmount),
                    tradeNo
            );
            return "success"; // 必须返回"success"给支付宝，否则会重复回调

        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    /**
     * 获取所有交易流水
     * @return 交易流水列表
     */
    @GetMapping("")
    public Result getAllTransactions() {
        try {
            List<Transaction> transactions = transactionService.getAllTransactions();
            return Result.getSuccess(transactions);
        } catch (Exception e) {
            return Result.error("获取交易流水列表失败: " + e.getMessage());
        }
    }
    // TransactionController.java
    /**
     * 根据订单ID获取交易流水
     * @param orderId 订单ID
     * @return 交易流水信息
     */
    @GetMapping("/by-order-id/{orderId}")
    public Result getTransactionByOrderId(@PathVariable Integer orderId) {
        try {
            Transaction transaction = transactionService.getTransactionByOrderId(orderId);
            if (transaction != null) {
                return Result.getSuccess(transaction);
            } else {
                return Result.error("未找到指定订单的交易流水");
            }
        } catch (Exception e) {
            return Result.error("获取交易流水详情失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID获取交易流水详情
     * @param transactionId 交易流水ID
     * @return 交易流水信息
     */
    @GetMapping("/{transactionId}")
    public Result getTransaction(@PathVariable Integer transactionId) {
        try {
            Transaction transaction = transactionService.getTransactionById(transactionId);
            if (transaction != null) {
                return Result.getSuccess(transaction);
            } else {
                return Result.error("未找到指定的交易流水");
            }
        } catch (Exception e) {
            return Result.error("获取交易流水详情失败: " + e.getMessage());
        }
    }
    /**
     * 添加交易流水
     * @param transaction 交易流水对象
     * @return 添加结果
     */
    @PostMapping("")
    public Result addTransaction(@RequestBody Transaction transaction) {
        try {
            transaction.setCreateTime(LocalDateTime.now());
            transaction.setUpdateTime(LocalDateTime.now());
            boolean result = transactionService.addTransaction(transaction);
            if (result) {
                return Result.saveSuccess("添加交易流水成功");
            } else {
                return Result.error("添加交易流水失败");
            }
        } catch (Exception e) {
            return Result.error("添加交易流水异常: " + e.getMessage());
        }
    }
    /**
     * 支付成功回调
     */
    @PostMapping("/payment/success")
    public Result paymentSuccess(@RequestParam Integer orderId) {
        try {
            // 获取订单信息
            OrderBase orderBase = orderBaseService.getOrderById(orderId);
            if (orderBase == null) {
                return Result.updateFail("订单不存在");
            }

            // 更新订单主表状态为已支付
            orderBase.setStatues(1); // 1表示已支付
            orderBase.setUpdateTime(LocalDateTime.now());
            orderBaseService.updateById(orderBase);

            // 同时更新订单详情表状态为已支付
            QueryWrapper<OrderDetail> detailWrapper = new QueryWrapper<>();
            detailWrapper.eq("order_id", orderId);
            OrderDetail updateDetail = new OrderDetail();
            updateDetail.setStatues(1); // 1表示已支付
            updateDetail.setUpdateTime(LocalDateTime.now());
            orderDetailService.update(updateDetail, detailWrapper);

            // 确认座位预订
            boolean result = seatStatusService.confirmBookingPermanently(
                    orderBase.getScheduleId(),
                    orderBase.getSeatCoordinates()
            );

            if (result) {
                return Result.updateSuccess("支付成功，座位预订确认");
            } else {
                return Result.updateFail("支付成功，但座位状态更新失败");
            }
        } catch (Exception e) {
            return Result.updateFail("支付处理异常: " + e.getMessage());
        }
    }
    /**
     * 更新交易流水
     * @param transactionId 交易流水ID
     * @param transaction 交易流水对象
     * @return 更新结果
     */
    @PutMapping("/{transactionId}")
    public Result updateTransaction(@PathVariable Integer transactionId, @RequestBody Transaction transaction) {
        try {
            transaction.setTransactionId(transactionId);
            transaction.setUpdateTime(LocalDateTime.now());
            boolean result = transactionService.updateTransaction(transaction);
            if (result) {
                return Result.updateSuccess("更新交易流水成功");
            } else {
                return Result.error("更新交易流水失败");
            }
        } catch (Exception e) {
            return Result.error("更新交易流水异常: " + e.getMessage());
        }
    }

    /**
     * 删除交易流水
     * @param transactionId 交易流水ID
     * @return 删除结果
     */
    @DeleteMapping("/{transactionId}")
    public Result deleteTransaction(@PathVariable Integer transactionId) {
        try {
            boolean result = transactionService.deleteTransaction(transactionId);
            if (result) {
                return Result.deleteSuccess("删除交易流水成功");
            } else {
                return Result.error("删除交易流水失败");
            }
        } catch (Exception e) {
            return Result.error("删除交易流水异常: " + e.getMessage());
        }
    }

}

